package common

import (
	"fmt"
	"github.com/google/uuid"
	"github.com/shirou/gopsutil/v3/net"
	"github.com/sony/sonyflake"
	"math/rand"
	"os"
	"strconv"
	"strings"
	"sync"
	"time"
)

// 100万次耗时: 1秒左右  ,10个并发,每次百万次耗时: 2秒左右  ,1万个并发,每次100次耗时: 2秒左右
var GlobalNumber = 10000000000    //11位 ,百亿
var MaxGlobalNumber = 99999999000 //11位 ,百亿
var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
var numberRunes = []rune("0123456789")
var macstr = "" //12位
var prestoreLock sync.Mutex
var sf *sonyflake.Sonyflake

func init() {
	// 获取本机的MAC地址
	interfaces, _ := net.Interfaces()
	for _, inter := range interfaces {
		localMac := inter.HardwareAddr //获取本机MAC地址
		//去掉:
		localMac = strings.ReplaceAll(string(localMac), ":", "")
		macstr = localMac
		break
	}
	settings := sonyflake.Settings{
		MachineID: func() (uint16, error) {
			// 从本机获取一个16位的机器标识
			//获取本机的ip地址
			s := GetLocalIp()[0]
			//去掉.
			s = strings.ReplaceAll(s, ".", "")
			//转换成uint16
			i, _ := strconv.Atoi(s)
			return uint16(i), nil
		},
	}
	var err error
	sf, err = sonyflake.New(settings)
	if err != nil {
		panic(err)
	}

}

var yucun = [100]string{}
var starIndex = 0
var yucunLock sync.Mutex

func init() {
	//初始化预存id
	for i := 0; i < 100; i++ {
		yucun[i] = randStringRunes()
	}
}

func randStringRunes() string {
	b := make([]rune, 10)
	//随机字母抽取5个
	for i := 0; i < 5; i++ {
		//随机数
		b[i] = letterRunes[rand.Intn(len(letterRunes))]
	}
	//随机数字抽取5个
	for i := 5; i < 10; i++ {
		//随机数
		b[i] = numberRunes[rand.Intn(len(numberRunes))]
	}
	//添加mac,地址 12位
	b = append(b, []rune(macstr)...)
	//时间戳,毫秒 13位
	nano := time.Now().UnixMilli()
	s := strconv.FormatInt(nano, 10)
	b = append(b, []rune(s)...)
	return string(b)
}

// 递增id生成
func RandStringRunesIncrement() int64 {
	var b = make([]rune, 0)
	//全局递增数字11位
	b = append(b, []rune(strconv.Itoa(GlobalNumber))...)

	prestoreLock.Lock()
	//判断是否超过最大值
	GlobalNumber++
	if GlobalNumber >= MaxGlobalNumber { //一旦超过最大值,则停机
		fmt.Println("百亿自增id耗尽,停机,重启后恢复")
		os.Exit(1)
	}
	prestoreLock.Unlock()
	//随机数字抽取4个
	for i := 0; i < 8; i++ {
		//随机数
		b = append(b, numberRunes[rand.Intn(len(numberRunes))])
	}
	//转换b
	return int64(GlobalNumber)
}

// 10+12+13=35   长度35位  百万亿级别的id生成 ,秒级生成,并发的情况下百万也能在4秒左右生成完毕
func RandStringRunes() string {
	yucunLock.Lock()
	defer yucunLock.Unlock()
	if starIndex == 99 {
		starIndex = 0
		//从新生成1000个预存id
		for i := 0; i < 100; i++ {
			yucun[i] = randStringRunes()
		}
	}
	starIndex++
	s := yucun[starIndex]
	return s
}

// uuid
func UUID() string {
	id := uuid.New()
	return id.String()
}

// 雪花算法生成id
func SnowflakeId() uint64 {
	id, err := sf.NextID()
	if err != nil {
		// 处理错误
		panic(err)
	}
	return id
}
